package com.eii.common.web.domain;

import com.eii.common.utils.JsonUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.SneakyThrows;
import org.springframework.http.HttpStatus;

import java.io.Serializable;
import java.util.Optional;

/**
 * 通用返回参数
 **/
@ApiModel(description = "通用返回值包装")
public class Result<T> implements Serializable {

    @ApiModelProperty(value = "数据")
    private T data;

    /**
     * 获取数据
     */
    public T getData() {
        return data;
    }

    @ApiModelProperty(value = "状态码", example = "200")
    private Integer code;

    /**
     * 获取状态
     */
    public int getCode() {
        return code;
    }

    @ApiModelProperty(value = "提示消息", example = "成功")
    private String msg;

    /**
     * 返回消息
     */
    public String getMsg() {
        return msg;
    }

    private Result(T data, Integer code, String msg) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    private Result(IResultCode resultCode) {
        this.code = resultCode.getCode();
        this.msg = resultCode.getDesc();
    }

    private Result(IResultCode resultCode, T data) {
        this.code = resultCode.getCode();
        this.data = data;
        this.msg = resultCode.getDesc();
    }

    private Result(IResultCode resultCode, String msg) {
        this.code = resultCode.getCode();
        this.msg = msg;
    }

    protected Result(IResultCode resultCode, T data, String msg) {
        this.code = resultCode.getCode();
        this.data = data;
        this.msg = msg;
    }

    /**
     * 获取json字符串(数组形式)
     */
    @SneakyThrows
    public byte[] jsonBytes() {
        return JsonUtil.toJSONBytes(this);
    }

    /**
     * 获取json字符串
     */
    public String json() {
        return new String(jsonBytes());
    }

    /**
     * 获取对应的HttpStatus
     */
    public HttpStatus httpStatus() {
        return ResultCode.of(code).getHttpStatus();
    }

    /**
     * 获取对应的状态枚举
     */
    public ResultCode resultCode() {
        return ResultCode.of(code);
    }

    /**
     * 判断返回是否为成功<br>
     * result不为null，且code为SUCCESS.code
     */
    public static boolean isSuccess(Result<?> result) {
        return Optional.ofNullable(result)
                .map(r -> ResultCode.SUCCESS.code == r.code)
                .orElse(Boolean.FALSE);
    }

    /**
     * 判断返回是否失败<br>
     * result为null，且code不为SUCCESS.code
     */
    public static boolean isNotSuccess(Result<?> result) {
        return !Result.isSuccess(result);
    }

    /**
     * 返回结果
     */
    public static <T> Result<T> of(ResultCode resultCode, T data, String msg) {
        return new Result<>(data, resultCode.getCode(), msg);
    }

    /**
     * 返回成功结果
     */
    public static <T> Result<T> success() {
        return new Result<>(ResultCode.SUCCESS);
    }

    /**
     * 返回成功结果
     */
    public static <T> Result<T> success(T data) {
        return new Result<>(ResultCode.SUCCESS, data);
    }

    public static <T> Result<T> success(T model, String msg) {
        return new Result<>(model, ResultCode.SUCCESS.getCode(), msg);
    }

    /**
     * 返回失败结果(有信息)
     */
    public static <T> Result<T> fail(String msg) {
        return of(ResultCode.FAILURE, null, msg);
    }

    /**
     * 返回失败结果(有数据,有信息)
     */
    public static <T> Result<T> fail(T model, String msg) {
        return of(ResultCode.FAILURE, model, msg);
    }

    /**
     * 返回失败结果
     */
    public static <T> Result<T> fail() {
        return new Result<>(ResultCode.FAILURE);
    }

    /**
     * 返回请求参数错误(无信息)
     */
    public static <T> Result<T> errorRequest() {
        return new Result<>(ResultCode.ERROR_PARAMETER);
    }

    /**
     * 返回请求参数错误(有信息)
     */
    public static <T> Result<T> errorRequest(String msg) {
        return new Result<>(ResultCode.ERROR_PARAMETER, msg);
    }

    /**
     * 返回服务器错误结果(无信息)
     */
    public static <T> Result<T> errorServe() {
        return new Result<>(ResultCode.ERROR_SERVER);
    }

    /**
     * 返回服务器错误结果(有信息)
     */
    public static <T> Result<T> errorServe(String message) {
        return new Result<>(ResultCode.ERROR_SERVER, message);
    }

    /**
     * 返回服务器错误结果(有信息)
     */
    public static <T> Result<T> errorServe(Throwable message) {
        return new Result<>(ResultCode.ERROR_SERVER, message.getMessage());
    }

    /**
     * 返回没找到请求结果 404
     */
    public static <T> Result<T> notFound() {
        return new Result<>(ResultCode.NOT_FOUND);
    }

    /**
     * 返回未登录结果
     */
    public static <T> Result<T> notLogin() {
        return new Result<>(ResultCode.NOT_LOGIN);
    }

    /**
     * 返回已过期结果
     */
    public static <T> Result<T> expired() {
        return new Result<>(ResultCode.EXPIRED);
    }

    /**
     * 返回未通过验证结果
     */
    public static <T> Result<T> noAuth() {
        return new Result<>(ResultCode.NO_AUTH);
    }

    /**
     * 返回缺少操作权限结果
     */
    public static <T> Result<T> noAccess() {
        return new Result<>(ResultCode.NO_ACCESS);
    }

    /**
     * 返回重复请求结果
     */
    public static <T> Result<T> repeatRequest() {
        return new Result<>(ResultCode.REPEAT_REQUEST);
    }

    /**
     * 返回服务器繁忙结果
     */
    public static <T> Result<T> busyServe() {
        return new Result<>(ResultCode.BUSY_SERVER);
    }

}
